<template>
	<el-scrollbar height="100%">
		<div class="color_box">
			<module_container title="从图片中获取颜色:">
				<div class="get_color_box">
					<el-upload
						drag
						:auto-upload="false"
						:show-file-list="false"
						class="upload"
						:on-change="file_change"
						v-if="is_show">
						<el-icon>
							<Plus />
						</el-icon>
					</el-upload>
					<canvas
						id="my_canvas"
						:width="max_size"
						:height="max_size"
						@click="get_pos"
						v-if="!is_show"></canvas>
					<div class="right_details">
						<div class="text">选中颜色的rgba值为:{{ color_dict.rgba_str }}</div>
						<div
							class="color_con"
							:style="{ background: color_dict.rgba_str }"></div>
						<div
							class="btn"
							@click="copy_color(color_dict.rgba_str)">
							复制rgba<span class="iconfont icon-fuzhi"></span>
						</div>
						<div class="text">选中颜色的Hex值为:{{ color_dict.hex_str }}</div>
						<div
							class="color_con"
							:style="{ background: color_dict.hex_str }"></div>
						<div
							class="btn"
							@click="copy_color(color_dict.hex_str)">
							复制Hex<span class="iconfont icon-fuzhi"></span>
						</div>
						<div
							class="btn"
							@click="clear_ctx">
							清除当前图片
						</div>
					</div>
				</div>
			</module_container>
			<module_container title="生成随机颜色:">
				<div class="random_color_box">
					<div class="row">
						<div
							class="btn"
							@click="generate_random_color('rgb')">
							生成随机rgb颜色
						</div>
						<div
							class="color_con"
							:style="{ background: random_color_dict.rgb_str }">
							{{ random_color_dict.rgb_str }}
						</div>
						<div
							class="btn copy"
							@click="copy_color(random_color_dict.rgb_str)">
							复制rgb<span class="iconfont icon-fuzhi"></span>
						</div>
					</div>
					<div class="row">
						<div
							class="btn"
							@click="generate_random_color('rgba')">
							生成随机rgba颜色
						</div>
						<div
							class="color_con"
							:style="{ background: random_color_dict.rgba_str }">
							{{ random_color_dict.rgba_str }}
						</div>
						<div
							class="btn copy"
							@click="copy_color(random_color_dict.rgba_str)">
							复制rgba<span class="iconfont icon-fuzhi"></span>
						</div>
					</div>
					<div class="row">
						<div
							class="btn"
							@click="generate_random_color('hex')">
							生成随机Hex颜色
						</div>
						<div
							class="color_con"
							:style="{ background: random_color_dict.hex_str }">
							{{ random_color_dict.hex_str }}
						</div>
						<div
							class="btn copy"
							@click="copy_color(random_color_dict.hex_str)">
							复制Hex<span class="iconfont icon-fuzhi"></span>
						</div>
					</div>
				</div>
			</module_container>
			<module_container title="颜色调整:">
				<div class="color_conversion_box">
					<div class="row">
						<el-input
							v-model="color_str"
							placeholder="请输入颜色值"
							style="width: 300px; height: 36px"
							@change="color_change"
							:spellcheck="false"></el-input>
						<div
							class="color_con"
							:style="{ background: color_str_copy }"></div>
					</div>
					<div class="row">
						<div class="row_text">
							<div>red:</div>
							<div>{{ color_list[0] }}</div>
						</div>
						<el-slider
							v-model="color_list[0]"
							show-input
							:debounce="200"
							:max="255"
							:min="0"
							size="small"
							@input="adjust_input" />
					</div>
					<div class="row">
						<div class="row_text">
							<div>green:</div>
							<div>{{ color_list[1] }}</div>
						</div>
						<el-slider
							v-model="color_list[1]"
							show-input
							:debounce="200"
							:max="255"
							:min="0"
							size="small"
							@input="adjust_input" />
					</div>
					<div class="row">
						<div class="row_text">
							<div>blue:</div>
							<div>{{ color_list[2] }}</div>
						</div>
						<el-slider
							v-model="color_list[2]"
							show-input
							:debounce="200"
							:max="255"
							:min="0"
							size="small"
							@input="adjust_input" />
					</div>
					<div
						class="row"
						v-if="color_list[3] !== undefined">
						<div class="row_text">
							<div>alpha:</div>
							<div>{{ color_list[3] }}</div>
						</div>
						<el-slider
							v-model="color_list[3]"
							show-input
							:debounce="200"
							:max="255"
							:min="0"
							size="small"
							@input="adjust_input" />
					</div>
					<div class="row">
						<div
							class="btn"
							@click="copying_changes('rgba', '0')">
							复制rgba<span class="iconfont icon-fuzhi"></span>
						</div>
						<div
							class="btn"
							@click="copying_changes('rgb', '0')">
							复制rgb<span class="iconfont icon-fuzhi"></span>
						</div>
						<div
							class="btn"
							@click="copying_changes('hex', '0')">
							复制Hex<span class="iconfont icon-fuzhi"></span>
						</div>
					</div>
				</div>
			</module_container>
			<module_container title="颜色明暗度:">
				<div class="color_brightness_box">
					<div class="row">
						<el-color-picker
							v-model="color_select"
							show-alpha
							:predefine="predefine_colors"
							@change="color_select_change" />
						<div
							class="color_con"
							:style="{ background: color_select_copy }"></div>
					</div>
					<div class="row">
						<el-radio-group
							v-model="radio"
							@change="radio_change">
							<el-radio
								:value="true"
								size="large"
								>变深</el-radio
							>
							<el-radio
								:value="false"
								size="large"
								>变浅</el-radio
							>
						</el-radio-group>
						<el-slider
							v-model="deep_shallow"
							show-input
							:debounce="500"
							:max="100"
							:min="0"
							size="small"
							@input="deep_shallow_input" />
					</div>
					<div class="row">
						<div
							class="btn"
							@click="copying_changes('rgba', '1')">
							复制rgba<span class="iconfont icon-fuzhi"></span>
						</div>
						<div
							class="btn"
							@click="copying_changes('rgb', '1')">
							复制rgb<span class="iconfont icon-fuzhi"></span>
						</div>
						<div
							class="btn"
							@click="copying_changes('hex', '1')">
							复制Hex<span class="iconfont icon-fuzhi"></span>
						</div>
					</div>
				</div>
			</module_container>
		</div>
	</el-scrollbar>
</template>

<script setup>
	import module_container from "@/components/module_container/index.vue";
	import { Plus } from "@element-plus/icons-vue";
	import { ref, onMounted, nextTick } from "vue";
	import {
		draw_image_to_canvas,
		get_color,
		split_colors,
		slider_input,
		lighten_color,
		darken_color,
	} from "@/utils/color.js";
	import { my_message } from "@/utils/my_message/index.js";
	import { useIndexStore } from "@/store/model/index";
	import { Events } from "@/utils/events_bus/index.js";

	const store = useIndexStore();
	const msg = my_message();

	const max_size = ref(300);
	let ctx = null;
	const is_show = ref(true);
	const color_dict = ref({});
	const random_color_dict = ref({
		rgba_str: "",
		hex_str: "",
		rgb_str: "",
	});
	const color_str = ref("");
	const color_str_copy = ref("");
	const color_list = ref([255, 255, 255, 255]);
	const predefine_colors = ref([...store.config.predefine_colors]);
	const color_select = ref(predefine_colors.value[0]);
	const color_select_copy = ref("");
	const color_select_list = ref([]);
	const radio = ref(true);
	const deep_shallow = ref(0);

	onMounted(() => {
		generate_random_color();
		let [r, g, b, a] = [...color_list.value];
		a = (a / 255).toFixed(2);
		color_str_copy.value = `rgba(${r}, ${g}, ${b}, ${a})`;
		color_select_copy.value = color_select.value;
	});

	const file_change = up_file => {
		const file = up_file.raw;
		is_show.value = false;
		nextTick(() => {
			const canvas = document.getElementById("my_canvas");
			ctx = canvas.getContext("2d", { willReadFrequently: true });
			ctx.imageSmoothingEnabled = true; // 关闭平滑
			ctx.imageSmoothingQuality = "high"; // 提高平滑质量
			if (file && file.type.startsWith("image/")) {
				draw_image_to_canvas(file, ctx, max_size.value);
				msg.msg_success("图片加载成功!");
				return;
			}
			is_show.value = true;
			msg.msg_error("图片加载失败!");
		});
	};

	const get_pos = e => {
		const offsetX = e.offsetX;
		const offsetY = e.offsetY;
		color_dict.value = get_color(offsetX, offsetY, ctx);
	};

	const copy_color = value => {
		if (!value) {
			msg.msg_warning("暂无数据，复制失败!");
			return;
		}
		Events.send_reply("write_text", value)
			.then(() => {
				msg.msg_success(`复制${value}成功!`);
			})
			.catch(err => {
				msg.msg_error("复制失败！");
			});
	};
	const clear_ctx = () => {
		if (is_show.value) {
			msg.msg_warning("暂无图片，清除失败!");
			return;
		}
		ctx.clearRect(0, 0, max_size.value, max_size.value);
		is_show.value = true;
		color_dict.value = {};
		msg.msg_success(`清除成功!`);
	};
	const generate_random_color = type => {
		const r = Math.floor(Math.random() * 256);
		const g = Math.floor(Math.random() * 256);
		const b = Math.floor(Math.random() * 256);
		const a = Math.random().toFixed(2);
		switch (type) {
			case "rgb":
				random_color_dict.value.rgb_str = `rgb(${r}, ${g}, ${b})`;
				break;
			case "rgba":
				random_color_dict.value.rgba_str = `rgba(${r}, ${g}, ${b}, ${a})`;
				break;
			case "hex":
				const rHex = r.toString(16).padStart(2, "0");
				const gHex = g.toString(16).padStart(2, "0");
				const bHex = b.toString(16).padStart(2, "0");
				random_color_dict.value.hex_str = `#${rHex}${gHex}${bHex}`;
				break;
			default:
				random_color_dict.value = {
					rgba_str: `rgba(${r}, ${g}, ${b}, ${a})`,
					hex_str: `#${r.toString(16).padStart(2, "0")}${g
						.toString(16)
						.padStart(2, "0")}${b.toString(16).padStart(2, "0")}`,
					rgb_str: `rgb(${r}, ${g}, ${b})`,
				};
				break;
		}
	};
	const color_change = v => {
		color_list.value = split_colors(v);
		color_str_copy.value = slider_input(color_list.value);
	};
	const adjust_input = () => {
		color_str_copy.value = slider_input(color_list.value);
	};
	const copying_changes = (type, flag) => {
		let r, g, b, a;
		if (flag === "0") {
			[r, g, b, a] = [...color_list.value];
		} else if (flag === "1") {
			[r, g, b, a] = [...color_select_list.value];
		}
		if (type === "rgba") {
			if (a === undefined) {
				a = 255;
			}
			a = Number((a / 255).toFixed(2));
			Events.send_reply("write_text", `rgba(${r}, ${g}, ${b}, ${a})`)
				.then(() => {
					msg.msg_success(`复制成功!`);
				})
				.catch(err => {
					msg.msg_error("复制失败！");
				});
		} else if (type === "rgb") {
			Events.send_reply("write_text", `rgb(${r}, ${g}, ${b})`)
				.then(() => {
					msg.msg_success(`复制成功!`);
				})
				.catch(err => {
					msg.msg_error("复制失败！");
				});
		} else if (type === "hex") {
			const rHex = r.toString(16).padStart(2, "0");
			const gHex = g.toString(16).padStart(2, "0");
			const bHex = b.toString(16).padStart(2, "0");
			let aHex;
			if (a !== undefined) {
				aHex = a.toString(16).padStart(2, "0");
				Events.send_reply("write_text", `#${rHex}${gHex}${bHex}${aHex}`)
					.then(() => {
						msg.msg_success(`复制成功!`);
					})
					.catch(err => {
						msg.msg_error("复制失败！");
					});
			} else {
				Events.send_reply("write_text", `#${rHex}${gHex}${bHex}`)
					.then(() => {
						msg.msg_success(`复制成功!`);
					})
					.catch(err => {
						msg.msg_error("复制失败！");
					});
			}
		}
	};
	const color_select_change = value => {
		deep_shallow.value = 0;
		if (!value) {
			color_select_copy.value = "rgba(0,0,0,1)";
			color_select.value = "rgba(0,0,0,1)";
			return;
		}
		color_select_copy.value = value;
	};
	const deep_shallow_input = v => {
		let list = split_colors(color_select.value);
		let data;
		// 变深
		if (radio.value) {
			data = darken_color(
				{
					r: list[0],
					g: list[1],
					b: list[2],
				},
				v
			);
		} else {
			data = lighten_color(
				{
					r: list[0],
					g: list[1],
					b: list[2],
				},
				v
			);
		}
		color_select_list.value = [...data, list[3] || 255];
		color_select_copy.value = slider_input(color_select_list.value);
	};
	const radio_change = () => {
		deep_shallow.value = 0;
		color_select_copy.value = color_select.value;
	};
</script>

<style lang="less" scoped>
	.color_box {
		width: 100%;
		height: 100%;
		padding: 15px;
		box-sizing: border-box;

		.get_color_box {
			display: flex;

			.upload {
				:deep(.el-upload-dragger) {
					padding: 0 !important;
					width: 300px;
					height: 300px;
					line-height: 300px;
					box-sizing: content-box;

					.el-icon {
						font-size: 50px;
					}
				}
			}

			#my_canvas {
				cursor: crosshair;
				border: var(--split-line);
			}

			.right_details {
				width: 300px;
				margin-left: 20px;
				display: flex;
				flex-direction: column;
				justify-content: space-between;

				.text {
					font-size: 14px;
				}
			}
		}

		.random_color_box {
			display: flex;

			.row {
				width: 300px;

				&:nth-child(n + 2) {
					margin-left: 20px;
				}

				.color_con {
					margin-top: 10px;
					color: #fff;
					text-align: center;
					line-height: 36px;
				}

				.copy {
					margin-top: 10px;
				}
			}
		}

		.color_conversion_box {
			.row {
				display: flex;

				&:nth-child(n + 2) {
					margin-top: 10px;
				}

				.btn {
					width: 300px;

					&:nth-child(n + 2) {
						margin-left: 20px;
					}
				}

				.color_con {
					margin-left: 20px;
				}

				.row_text {
					width: 300px;
					display: flex;
					justify-content: space-between;
					align-items: center;
				}

				.el-slider {
					margin-left: 20px;
					width: 400px;
				}
			}
		}

		.color_brightness_box {
			.row {
				display: flex;
				align-items: center;

				&:nth-child(n + 2) {
					margin-top: 10px;
				}
				.color_con {
					margin-left: 20px;
				}

				:deep(.el-color-picker) {
					width: 300px;
					height: 36px;

					.el-color-picker__trigger {
						width: 100%;
						height: 100%;
					}
				}

				.el-radio-group {
					width: 300px;
					display: flex;
					justify-content: space-between;
				}
				.el-slider {
					margin-left: 20px;
					width: 400px;
				}
				.btn {
					width: 300px;

					&:nth-child(n + 2) {
						margin-left: 20px;
					}
				}
			}
		}

		.color_con {
			width: 300px;
			box-sizing: border-box;
			height: 36px;
			border: var(--split-line);
		}
	}
</style>
